import { Command } from 'commander';
import { api } from '../services/api';
import { config } from '../services/config';
import { logger } from '../utils/logger';
import { requireAuth, requireProject } from '../utils/validation';
import { CLIError } from '../types';

export function debugCommands(program: Command): void {
  program
    .command('call <action>')
    .description('Call a module action')
    .option('--input <json>', 'Input data as JSON string')
    .option('-m, --module <module>', 'Module name')
    .option('-e, --env <env>', 'Target environment')
    .action(async (actionName: string, options) => {
      try {
        requireAuth();
        const projectId = requireProject();
        
        if (!options.module) {
          throw new CLIError('Module name is required. Use --module <name>');
        }

        let targetEnv = options.env || config.getCurrentEnvironment();
        let input = {};
        
        if (options.input) {
          try {
            input = JSON.parse(options.input);
          } catch (error) {
            throw new CLIError('Invalid JSON input');
          }
        }

        const spinner = logger.spinner(`Calling ${options.module}.${actionName}...`);
        try {
          const environments = await api.getEnvironments(projectId);
          const environment = environments.find(e => e.name === targetEnv);
          
          if (!environment) {
            throw new CLIError(`Environment "${targetEnv}" not found`);
          }

          const result = await api.callModuleAction(projectId, environment.id, options.module, actionName, input);
          spinner.succeed();
          
          logger.success('Action executed successfully');
          logger.log('\nResult:');
          logger.log(JSON.stringify(result, null, 2));
        } catch (error) {
          spinner.fail();
          throw error;
        }
      } catch (error) {
        if (error instanceof CLIError) {
          throw error;
        }
        throw new CLIError('Failed to call module action');
      }
    });

  program
    .command('logs <module>')
    .description('View module logs')
    .option('-e, --env <env>', 'Target environment')
    .action(async (moduleName: string, options) => {
      try {
        requireAuth();
        const projectId = requireProject();
        
        let targetEnv = options.env || config.getCurrentEnvironment();

        const spinner = logger.spinner(`Fetching logs for ${moduleName}...`);
        try {
          const environments = await api.getEnvironments(projectId);
          const environment = environments.find(e => e.name === targetEnv);
          
          if (!environment) {
            throw new CLIError(`Environment "${targetEnv}" not found`);
          }

          const logs = await api.getModuleLogs(projectId, environment.id, moduleName);
          spinner.succeed();
          
          if (logs.length === 0) {
            logger.info('No logs found');
            return;
          }

          logger.log(`\nLogs for ${moduleName}:`);
          logs.forEach(log => {
            logger.log(log);
          });
        } catch (error) {
          spinner.fail();
          throw error;
        }
      } catch (error) {
        if (error instanceof CLIError) {
          throw error;
        }
        throw new CLIError('Failed to fetch logs');
      }
    });

  program
    .command('doctor')
    .description('Check project health and configuration')
    .action(async () => {
      try {
        requireAuth();
        const projectId = requireProject();
        const currentEnv = config.getCurrentEnvironment();

        logger.info('Running health check...');
        
        const spinner = logger.spinner('Analyzing project configuration...');
        try {
          const project = await api.getProject(projectId);
          const environments = await api.getEnvironments(projectId);
          const environment = environments.find(e => e.name === currentEnv);
          
          spinner.succeed();

          logger.log('\n=== Project Health Report ===\n');
          
          logger.success(`✓ Project: ${project.name}`);
          logger.success(`✓ Current environment: ${currentEnv}`);
          
          if (!environment) {
            logger.error(`✗ Environment "${currentEnv}" not found`);
            return;
          }

          const moduleCount = environment.modules?.length || 0;
          const secretCount = Object.keys(environment.secrets || {}).length;
          
          if (moduleCount === 0) {
            logger.warning('⚠ No modules installed');
          } else {
            logger.success(`✓ ${moduleCount} modules installed`);
          }
          
          if (secretCount === 0) {
            logger.warning('⚠ No secrets configured');
          } else {
            logger.success(`✓ ${secretCount} secrets configured`);
          }
          
          logger.log('\n=== Recommendations ===\n');
          
          if (moduleCount === 0) {
            logger.info('• Install modules with "cm add <module>"');
          }
          
          if (secretCount === 0) {
            logger.info('• Configure secrets with "cm secret set KEY=VALUE"');
          }
          
          if (environments.length === 1) {
            logger.info('• Create additional environments with "cm env create <name>"');
          }
        } catch (error) {
          spinner.fail();
          throw error;
        }
      } catch (error) {
        if (error instanceof CLIError) {
          throw error;
        }
        throw new CLIError('Health check failed');
      }
    });
}